﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Demo.Framework.PostProcessing
{
    internal class PostProcessor
    {
        // Pixel shader
        public Effect Effect { get; protected set; }

        // Texture to process
        public Texture2D Input { get; set; }

        // GraphicsDevice and SpriteBatch for drawing
        protected GraphicsDevice GraphicsDevice;
        protected static SpriteBatch SpriteBatch;

        public PostProcessor(Effect effect, GraphicsDevice graphicsDevice)
        {
            this.Effect = effect;

            if (SpriteBatch == null)
                SpriteBatch = new SpriteBatch(graphicsDevice);

            this.GraphicsDevice = graphicsDevice;
        }

        // Draws the input texture using the pixel shader postprocessor
        public virtual void Draw()
        {
            // Set effect parameters if necessary
            if (Effect.Parameters["ScreenWidth"] != null)
                Effect.Parameters["ScreenWidth"].SetValue(
                    GraphicsDevice.Viewport.Width);

            if (Effect.Parameters["ScreenHeight"] != null)
                Effect.Parameters["ScreenHeight"].SetValue(
                    GraphicsDevice.Viewport.Height);

            // Initialize the spritebatch and effect
            SpriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque);
            Effect.CurrentTechnique.Passes[0].Apply();

            // For reach compatiblity
            GraphicsDevice.SamplerStates[0] = SamplerState.AnisotropicClamp;

            // Draw the input texture
            SpriteBatch.Draw(Input, Vector2.Zero, Color.White);

            // End the spritebatch and effect
            SpriteBatch.End();

            // Clean up render states changed by the spritebatch
            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            GraphicsDevice.BlendState = BlendState.Opaque;
        }
    }
}
